<?php


/**
 * 载入淘宝 api 处理类
 */
require('taoapi/Taoapi.php');

/**
 * 载入缓存处理类
 */
require('sync/cache.php');

/**
 * 载入属性（值）处理类
 */
require('sync/props.php');

/**
 * 载入产品处理类
 */
require('sync/products.php');

/**
 * 载入同步异常处理类
 */
require('sync/exception.php');

/**
 * 定义行分隔符
 */
define('LINE_SEP', "\n------------------------------------------------------------------\n");

/**
 * 淘宝数据同步
 *
 * @copyright  www.360hqb.com
 * @author   Y.N
 *
 */
class CLI_Sputb extends CLI
{

	/**
	 * CLI主方法
	 *
	 * @param	none
	 * @access	public
	 * @return	void
	 * @update	2011/4/19
	*/
	public function main()
	{
		$page = $this->args->page;
		if ($page)
		{
			self::sync_data($page);
		}


	} // end func


	/**
	 * 获取淘宝最顶层类目（写入缓存）
	 *
	 * @param	none
	 * @access	public
	 * @return	array
	 * @update	2011/3/24
	*/
	public static function get_taobao_top_cats()
	{
		// 获取缓存
		$Sync_Cache = new Sync_Cache();
		$top_cats = json_decode($Sync_Cache->get_cache('topcats'));
		if (empty($top_cats))
		{
		    $top_cats = self::get_taobao_cats(0);
			// 写入缓存
			$data = json_encode($top_cats);
			$Sync_Cache->save_cache('topcats',$data);
		}
		return $top_cats;
	} // end func

	/**
	 * 获取360hqb子叶类目
	 *
	 * @param	int $parent_cid
	 * @access	public
	 * @return	array
	 * @update	2011/3/22
	*/
	public static function get_root_cats($parent_cid = 0)
	{
		$root_cats = array();

		$item_cats = DB::select('cid')
			->from('item_cats')
			->where('parent_cid', '=',$parent_cid)
			->fetch_all();

		if ($item_cats)
		{
			foreach ($item_cats as $key => $value)
			{
				$root_cats = array_merge($root_cats,self::get_root_cats($value['cid']));
			}
		}else {
			$root_cats[] = $parent_cid;
		}
		return $root_cats;
	} // end func


	/**
	 * 通过API获取淘宝类目数据
	 *
	 * @param	int $cid
	 * @access	public
	 * @return	object
	 * @update	2011/3/22
	*/
	public static function get_taobao_cats($cid)
	{
		// 判断是否数字类型
		assert("is_numeric('$cid')");
		$url = "http://open.taobao.com/api_tool/props/ajaxProps.php?cid=$cid&action=childCid&restBool=false";

		// 获取数据
		$i = 1;
		while (true) {
			$data = @file_get_contents($url);
			if ($data !== false) {
                break;
			} else {
                CLI::output ('.');
                sleep($i++);
			}
		}

		// 反编码
        $std = json_decode($data);
		if ( ! empty($data))
		{
		    return isset($std->itemcats_get_response->item_cats->item_cat) ?
                $std->itemcats_get_response->item_cats->item_cat :
                new stdClass();
		}else {
		    return new stdClass();
		}
	} // end func


	/**
	 * 匹配需要新增（下载）的子叶类目
	 *
	 * @param	none
	 * @access	public
	 * @return	array
	 * @update	2011/3/22
	*/
	public static function match_sync_cats()
	{
	    CLI::output(LINE_SEP."正在获取新增（下载）子叶类目数据...");

		// 获取360hqb需要新增（下载）的子叶类目
		$sync_cats = DB::select()
			->from('sync_cats')
			->where('deleted', '=',0)
			->fetch_all();

		$new_cats = array();
		if ($sync_cats)
		{
			CLI::output(LINE_SEP."正在匹配新增（下载）子叶类目...");
			$explode = array();
		    foreach ($sync_cats as $k=>$sc)
			{
				// 拆分新增类目
				$explode = explode('>>',$sc['local']);

				$cid = 0; $datas = array();
				foreach ($explode as $key => $e)
				{
					// 检测类目
					$data = self::check_sync_cats(trim($e), $cid);
					if ($data)
					{
						$cid = $data->cid;
						$datas[] = $data;
					}
				}
				// 类目是否完全匹配
				if (count($datas) == count($explode))
				{
					$end_data = end($datas);
					if ($end_data->is_parent == 1)
					{
					    $set = array(
							'deleted' => 1,
							'msg' => '同步失败,此类目不是子叶类目'
						);
					}else {
						$set = array(
							'deleted' => 1,
							'msg' => '同步成功'
						);
					    $new_cats[] =$datas;
					}
				}else {
					$set = array(
						'deleted' => 1,
						'msg' => '同步失败，未找到类目数据'
					);
				}
				unset($datas, $explode);
				DB::update('sync_cats')->set($set)->where('id', '=',$sc['id'])->execute();
			}
			CLI::output(LINE_SEP."匹配新增（下载）子叶类目完毕");
		}
		return $new_cats;
		unset($new_cats);
	} // end func

	/**
	 * 检测是否可下载的子叶类目
	 *
	 * @param	string $value
	 * @param	int $parent_cid
	 * @access	public
	 * @return	array
	 * @update	2011/3/24
	*/
	public static function check_sync_cats($value, $parent_cid)
	{
		$return = array();

		if ($parent_cid)
		{
		    $cats = self::get_taobao_cats($parent_cid);
		}else {
		    $cats = self::get_taobao_top_cats();
		}
		foreach ($cats as $k => $cat)
		{
			if ($value == $cat->name)
			{
			    $return = $cat;
			}
		}
		return $return;
	} // end func


	/**
	 * 保存新增（下载）的子叶类目
	 *
	 * @param	none
	 * @access	public
	 * @return	void
	 * @update	2011/3/24
	*/
	public static function save_sync_cats()
	{
		// 获取已匹配成功的新增（下载）类目
	    $add_cats = self::match_sync_cats();

		if ( ! empty($add_cats))
		{
			CLI::output(LINE_SEP."正在保存新增（下载）子叶类目...");
		    foreach ($add_cats as $cat)
		    {
				if (is_array($cat))
				{
				    foreach ($cat as $k => $c )
				    {
						// 是否已存在
						$count = DB::select(DB::expr('COUNT(*)'))
							->from('item_cats')
							->where('cid', '=', $c->cid)
							->fetch_one();
						if ( ! $count)
						{
							// 写入日志
							new Sync_Exception('新增类目：('.$c->name.'['.$c->cid.'])', 267, __FUNCTION__, __CLASS__);

							$row = array(
								'cid' => $c->cid,
								'parent_cid' => $c->parent_cid,
								'name' => $c->name,
								'is_parent' => $c->is_parent ? 1 : 0,
								'deleted' => (isset($c->status) && strtolower($c->status) == 'deleted') ? 1 : 0,
								'sort_order' => isset($c->sort_order) ? $c->sort_order : 0,
							);
							DB::insert('item_cats', array_keys($row))
								->values(array_values($row))
								->execute();
						}
				    }
				}
		    }
			CLI::output(LINE_SEP."保存新增（下载）子叶类目完毕");
		}
	} // end func


	/**
	 * 获取淘宝属性（值）写入文件
	 *
	 * @param	none
	 * @access	public
	 * @return	void
	 * @update	2011/5/5
	*/
	public static function save_taobao_data($page_no = 1)
	{
		// 自动退出时间
		$time = strtotime(date('Y-m-d 08:15:s'));

		$Sync_Cache = new Sync_Cache();
		if ($Sync_Cache->get_cache('save_taobao_data_'.$page_no))
		{
			exit;
		}
		CLI::output(LINE_SEP."正在获取子叶类目数据...");

		// 获取子叶类目缓存
		$date = date("Ymd");
		$data = $Sync_Cache->get_cache('rootcats_'.$date);
		$root_cats = json_decode($data);
		if (empty($root_cats))
		{
		    $root_cats = self::get_root_cats();
			$Sync_Cache->save_cache('rootcats_'.$date, json_encode($root_cats));
		}

		// 过滤的ID
		$filter = array(50012580,50012579);

		// 页数
		$page_size = 10;
		$offset = ($page_no - 1) * $page_size;
		$current_data = array_slice($root_cats, $offset, $page_size);

		foreach ($current_data as $k => $c)
		{
			// 自动退出脚本
			if (time() >= $time)
			{
				exit('自动退出脚本');
			}
			if ($Sync_Cache->get_cache('cats_'.$c))
			{
				continue;
			}
			// 检测是否锁定分类
			if (self::locked($c) or in_array($c,$filter))
			{
				new Sync_Exception('子叶类目：('.$c.') 已被锁定', 312, __FUNCTION__, __CLASS__);
			    continue;
			}
			// 获取淘宝属性（值）数据
			CLI::output(LINE_SEP."子叶分类ID (".$c.") 获取属性（值）开始...");

			$std = Sync_Props::get_taobao_props($c);
			CLI::output(LINE_SEP."子叶分类ID (".$c.") 同步属性开始...");
			Sync_Props::save_props($std->props,$c);

			CLI::output(LINE_SEP."子叶分类ID (".$c.") 同步（属性值）开始...");
			Sync_Props::save_prop_values($std->propvalues,$c);

			CLI::output(LINE_SEP."子叶分类ID (".$c.") 获取属性（值）结束");

			$Sync_Cache->save_cache('cats_'.$c, 1);
			unset($std);
		}
	} // end func



	/**
	 * 判断分类下载是否锁定
	 *
	 * @param  int  $cid
	 * @return bool
	 */
	public static function locked($cid)
	{
		return is_file(TMPPATH."/logs/lock/$cid.lock");
	}

	/**
	 * 锁定分类下载
	 *
	 * @param  int  $cid
	 * @param  int  $total
	 */
	public static function lock($cid, $total = 0)
	{
		$path = TMPPATH."/logs/lock/";
		$file = $path."$cid.lock";
		if ( ! dir($path))
		{
		    mkdir($path, 0777);
		}
		file_put_contents($file, $total);
	}

	/**
	 * 同步所有数据
	 *
	 * @param	none
	 * @access	public
	 * @return	void
	 * @update	2011/3/22
	*/
	public static function sync_data($page = 1)
	{
		// 创建缓存实例
		$Sync_Cache = new Sync_Cache();

		// 获取同步类目缓存
		$save_sync_cats = $Sync_Cache->get_cache('save_sync_cats');

		// 缓存时间为2天，如果2天内已经同步过不再同步
		if ( ! $save_sync_cats)
		{
		    // 写入日志
			new Sync_Exception('|-------|同步类目开始', ':',  __FUNCTION__, __CLASS__);
			// 同步新增类目
			self::save_sync_cats();

			// 同步结束，写入缓存
			$Sync_Cache->save_cache('save_sync_cats', 1);

			new Sync_Exception('|-------|同步类目结束', ':',  __FUNCTION__, __CLASS__);
		}

		// 获取同步属性缓存
		$save_taobao_data = $Sync_Cache->get_cache('save_taobao_data_'.$page);
		if ( ! $save_taobao_data)
		{
		    // 写入日志
			new Sync_Exception('|-------|同步属性（值）开始', $page,  __FUNCTION__, __CLASS__);
			/** 同步属性（值） **/

			// 下载
			self::save_taobao_data($page);

			// 同步结束，写入缓存
			$Sync_Cache->save_cache('save_taobao_data_'.$page, 1);

			new Sync_Exception('|-------|同步属性（值）结束', $page,  __FUNCTION__, __CLASS__);
		}

	} // end func


} // end class





